﻿using System;
using EmbeddedSharp.Core;
using Zove.Runtime.Core;
using Zove.Runtime.Core.Zoom;

namespace Zove.Scripting.Core.Functions
{
    /// <summary>
    /// Produce an expression for the factor.
    /// </summary>
    [Function("formulate", "Formulate an expression for the factor.",
        "circle c;\n\rc.r=10;\n\rarea=formulate(c.area);", "area==3.1415926*r^2")]
    public class FormulateNode : ZoveScriptingContextFuncNode
    {
        /// <summary>
        /// Default constructor
        /// </summary>
        public FormulateNode()
        {
            base.Value = "formulate";
        }

        /// <summary>
        /// Produce the expression.
        /// </summary>
        /// <returns>the resultant expression</returns>
        public override object Evaluate()
        {
            if (Parameters.Count < 1)
            {
                throw new ArgumentException(
                    "usage: formulate(factor)");
            }

            RuntimeFactor factor
                = ZoveShellContext.GetFactor(
                    Parameters[Parameters.Count - 1].Value);
            if (factor.Status == RuntimeFactorStatus.Unknown)
            {
                throw new Exception(
                    string.Format(
                        "Cannot produce an expression for factor '{0}' due to its unknown status.",
                        factor.QualifiedName));
            }

            string instanceName = factor.Model.Instance.Name;
            var ss = new SolutionFormulator();
            string result = ss.Formulate(factor);
            //result = Utils.Prefixize(instanceName, result,
            //    ZoveDependencyManager.Instance.FunctionManager);

            //var rm = (ZoveObject)Context.GetVariable(instanceName);
            //ZoomLanguageNature languageNature = new ZoomLanguageNature();
            ExpressionParser parser = Context.GetParserFactory().CreateParser(result);
            Node root = parser.Parse();

            if (Parameters.Count < 2)
            {
                return root;
            }
            string var = Parameters[Parameters.Count - 2].Value;
            var t
                = new FormulateExpressionTranslator(var);
            string ret = t.Translate(root);
            return ret;
        }

        /// <summary>
        /// Returns the formulated expression
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Evaluate().ToString();
        }
    }
}